#pragma once
#include<string>
#include <vector>
#include <utility>
#include "vector3.h"
#include "Material.h"
#include "Misc.h"
#include "Iterator.h"
#include "triangle.h"
#include "BOX.h"
#include "Kdtree.h"



namespace RayTrace{

	class Object
	{
		//struct MaterialFaces {
		//	std::vector<unsigned short> subFaces;	// Index to our vertex array of all the faces that use this material
		//	//int numSubFaces;			// The number of faces
		//	int MatIndex;				// An index to our materials
		//};


	public:
		Object(void);
		virtual ~Object(void);

		std::string name;				        // The object name rather than file name
		std::vector<vector3> Vertices;			// The array of vertices
		std::vector<vector3> Normals;			// The array of the normals for the vertices
		std::vector<TexCoordinate> TexCoords;	// The array of texture coordinates for the vertices
		std::vector<Face> Faces;		        // The array of face 
		std::vector<MaterialFaces> MatFaces;	// The faces are divided by materials

		//int numFaces;				// The number of faces
		//int numMatFaces;			// The number of differnet material faces
		//int numVerts;				// The number of vertices
		//int numTexCoords;			// The number of vertices
		//std::vector<MaterialFaces> MatFaces;	// The faces are divided by materials
		vector3 pos;					// The position to move the object to
		vector3 rot;		

		bool textured;				// True: the object has textures
		CBOX aabb;
		CKdtree kdtree;				//depend on bounding box,so execute GenGoundingBox() first;
		

	public:
		size_t GetVertexsNum(){return Vertices.size();}
		CTriangle GetTriangleFromFace(const Face & face) const;
		vector3 GetNormalFromBarycentric( const Face & face ,const vector3& barycentric) const;
		void GenBoundingBox();
		void GenKdtree();//depend on bounding box,so execute GenGoundingBox() first;
		bool IsIntersect(const Ray& ray);
		double Intersect(const Ray& ray,int& faceindex);


	


		class FaceIterator:public Iterator
		{
		public:
			FaceIterator();
			FaceIterator(Object * pObj);
			~FaceIterator(void);
			void initial(Object * pObj);
			void first();
			bool isDone();
			void next();
			size_t materialIndex();
			const Face& face();
			CTriangle triangle();
			vector3 GetNormalFromBarycentric(const vector3& barycentric);
			bool operator==(const FaceIterator&) const;
	
		protected:
			Object * mObject;
			size_t mMatFaceIndex;
			size_t mSubFaceIndex;
		};
	};

}